package instruction

import (
	"gitee.com/microwww/jvm-go/jvm/rtda"
)

// 比较指令

type LCMP struct {
	Noop
}

func (f *LCMP) Execute(fm *rtda.MethodFrame) {
	stack := fm.OperationStack()
	cmp := stack.PopLong()
	v := stack.PopLong()
	if cmp > v {
		stack.PushInt(-1)
	} else if cmp == v {
		stack.PushInt(0)
	} else {
		stack.PushInt(1)
	}
}

// 如果两个float 无法比较的时候 比较结果 ? `NaN`
func f_cmp(fm *rtda.MethodFrame, NaN int32) {
	stack := fm.OperationStack()
	cmp := stack.PopFloat()
	v := stack.PopFloat()
	if cmp > v {
		stack.PushInt(-1)
	} else if cmp == v {
		stack.PushInt(0)
	} else if cmp < v {
		stack.PushInt(0)
	} else {
		stack.PushInt(NaN)
	}
}

type FCmpG struct {
	Noop
}

func (f *FCmpG) Execute(fm *rtda.MethodFrame) {
	f_cmp(fm, 1)
}

type FCmpL struct {
	Noop
}

func (f *FCmpL) Execute(fm *rtda.MethodFrame) {
	f_cmp(fm, -1)
}
func d_cmp(fm *rtda.MethodFrame, NaN int32) {
	stack := fm.OperationStack()
	cmp := stack.PopDouble()
	v := stack.PopDouble()
	if cmp > v {
		stack.PushInt(-1)
	} else if cmp == v {
		stack.PushInt(0)
	} else if cmp < v {
		stack.PushInt(0)
	} else {
		stack.PushInt(NaN)
	}
}

type DCmpG struct {
	Noop
}

func (f *DCmpG) Execute(fm *rtda.MethodFrame) {
	d_cmp(fm, 1)
}

type DCmpL struct {
	Noop
}

func (f *DCmpL) Execute(fm *rtda.MethodFrame) {
	d_cmp(fm, -1)
}
